#include "common.h"
#include "memory/cache.h"
#include <stdlib.h>
#include "burst.h"
uint32_t dram_read(hwaddr_t, size_t);
void dram_write(hwaddr_t, size_t, uint32_t);
int is_mmio(hwaddr_t);
uint32_t mmio_read(hwaddr_t, size_t, int);
void mmio_write(hwaddr_t, size_t, uint32_t, int);

/* Memory accessing interfaces */

uint32_t hwaddr_read(hwaddr_t addr, size_t len) {
	    int32_t set_l1 = (addr >> block_bits) & (l1_sets - 1);
    int32_t i = l1_read(addr);
    int32_t imm_l1 = (addr & (CACHE_BLOCK_SIZE - 1));
    int8_t tmp [CACHE_BLOCK_SIZE * 2];
    if(imm_l1 + len > CACHE_BLOCK_SIZE) {
        memcpy(tmp, cache1[set_l1][i].block + imm_l1, CACHE_BLOCK_SIZE - imm_l1);                                   // 复制第一个块的内容
        int32_t i_last = l1_read(addr + CACHE_BLOCK_SIZE - imm_l1);
        int32_t set_last = ((addr + CACHE_BLOCK_SIZE - imm_l1) >> block_bits) & (l1_sets - 1);
        memcpy(tmp + CACHE_BLOCK_SIZE - imm_l1, cache1[set_last][i_last].block, len - (CACHE_BLOCK_SIZE - imm_l1));     // 复制剩下的第2个块
    }
    else memcpy(tmp, cache1[set_l1][i].block + imm_l1, len);
    int qwq = 0; uint32_t result = unalign_rw(tmp + qwq, 4) & (~0u >> ((4 - len) << 3));                   //  在nemu/include/macro.h
	return result;
}

void hwaddr_write(hwaddr_t addr, size_t len, uint32_t data) {
	l1_write(addr, len, data);
}

uint32_t lnaddr_read(lnaddr_t addr, size_t len) {
	return hwaddr_read(addr, len);
}

void lnaddr_write(lnaddr_t addr, size_t len, uint32_t data) {
	hwaddr_write(addr, len, data);
}

uint32_t swaddr_read(swaddr_t addr, size_t len) {
#ifdef DEBUG
	assert(len == 1 || len == 2 || len == 4);
#endif
	return lnaddr_read(addr, len);
}

void swaddr_write(swaddr_t addr, size_t len, uint32_t data) {
#ifdef DEBUG
	assert(len == 1 || len == 2 || len == 4);
#endif
	lnaddr_write(addr, len, data);
}

